<template>
  <div class="area-select">
    <el-cascader
      v-model="selectedArea"
      :options="areaOptions"
      :props="cascaderProps"
      placeholder="请选择省市区"
      clearable
      filterable
      @change="handleAreaChange"
      style="width: 100%"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch } from 'vue';
import { getNbSysAreaControlList } from '@/api/wechat';
import { ElMessage } from 'element-plus';

interface AreaItem {
  areaCode: string;
  areaName: string;
  areaType: string;
  parentCode: string;
  treeLevel: number;
  children?: AreaItem[];
}

interface CascaderOption {
  value: string;
  label: string;
  children?: CascaderOption[];
  leaf?: boolean;
}

interface Props {
  modelValue?: string[];
  placeholder?: string;
}

interface Emits {
  (e: 'update:modelValue', value: string[]): void;
  (e: 'change', value: string[], selectedData: AreaItem[]): void;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => [],
  placeholder: '请选择省市区'
});

const emit = defineEmits<Emits>();

const selectedArea = ref<string[]>([]);
const areaOptions = ref<CascaderOption[]>([]);

// 级联选择器配置
const cascaderProps = reactive({
  value: 'value',
  label: 'label',
  children: 'children',
  lazy: true,
  checkStrictly: true, // 允许选择任意一级
  lazyLoad: async (node: any, resolve: any) => {
    const { level, value } = node;

    try {
      // 根据层级加载不同的数据
      let areaCode = '';
      if (level === 0) {
        // 加载省级数据，不传areaCode
        areaCode = '';
      } else {
        // 加载市级或区级数据
        areaCode = value;
      }

      const response = await getNbSysAreaControlList(areaCode);
      const data = response.data;

      if (data) {
        const options: CascaderOption[] = [];

        // 处理按字母分组的数据结构
        Object.keys(data).forEach((letter) => {
          const areas = data[letter];
          if (Array.isArray(areas)) {
            areas.forEach((area: AreaItem) => {
              // 保存地区代码到名称的映射
              areaCodeToNameMap.value.set(area.areaCode, area.areaName);

              options.push({
                value: area.areaCode,
                label: area.areaName,
                leaf: area.treeLevel >= 2 // 区级为叶子节点，但允许选择任意级别
              });
            });
          }
        });

        // 按名称排序
        options.sort((a, b) => a.label.localeCompare(b.label, 'zh-CN'));
        resolve(options);
      } else {
        resolve([]);
      }
    } catch (error) {
      console.error('加载地区数据失败:', error);
      ElMessage.error('加载地区数据失败');
      resolve([]);
    }
  }
});

// 监听外部传入的值变化
watch(
  () => props.modelValue,
  (newVal) => {
    selectedArea.value = newVal || [];
    console.log('AreaSelect 接收到外部值变化:', newVal);
  },
  { immediate: true }
);

// 监听选择变化
watch(selectedArea, (newVal) => {
  emit('update:modelValue', newVal);
});

// 存储地区代码到名称的映射
const areaCodeToNameMap = ref<Map<string, string>>(new Map());

// 处理地区选择变化
const handleAreaChange = async (value: string[]) => {
  if (!value || value.length === 0) {
    emit('change', [], []);
    return;
  }

  try {
    // 获取选中地区的详细信息
    const selectedData: AreaItem[] = [];

    // 根据选中的地区代码获取地区名称
    for (let i = 0; i < value.length; i++) {
      const code = value[i];
      const name = areaCodeToNameMap.value.get(code);
      if (name) {
        selectedData.push({
          areaCode: code,
          areaName: name,
          areaType: '',
          parentCode: '',
          treeLevel: i // 使用索引作为层级：0-省，1-市，2-区
        });
      }
    }

    // 构造省市区名称对象
    const areaNames = {
      userProName: selectedData[0]?.areaName || '', // 省份名称
      userCityName: selectedData[1]?.areaName || '', // 地市名称
      userCountyName: selectedData[2]?.areaName || '' // 区县名称
    };

    emit('change', value, { selectedData, areaNames });
  } catch (error) {
    console.error('获取地区详情失败:', error);
    emit('change', value, []);
  }
};

// 初始化加载省级数据
onMounted(async () => {
  try {
    const response = await getNbSysAreaControlList();
    const data = response.data;

    if (data) {
      const options: CascaderOption[] = [];

      // 处理按字母分组的数据结构
      Object.keys(data).forEach((letter) => {
        const areas = data[letter];
        if (Array.isArray(areas)) {
          areas.forEach((area: AreaItem) => {
            // 保存地区代码到名称的映射
            areaCodeToNameMap.value.set(area.areaCode, area.areaName);

            options.push({
              value: area.areaCode,
              label: area.areaName,
              leaf: false // 省级不是叶子节点
            });
          });
        }
      });

      // 按名称排序
      options.sort((a, b) => a.label.localeCompare(b.label, 'zh-CN'));
      areaOptions.value = options;
    }
  } catch (error) {
    console.error('初始化地区数据失败:', error);
    ElMessage.error('初始化地区数据失败');
  }
});
</script>

<style scoped lang="scss">
.area-select {
  width: 100%;
}
</style>
